grammar OpenQASM2;

// 定义文件入口
mainprogram : 'OPENQASM' real ';' program EOF;

program
    : statement*
    ;

// 声明语句
statement
    : includeStatement            // 新增文件包含语句
    | decl                        // 量子或经典寄存器声明
    | gatedecl                    // 空门定义
    | 'opaque' ID idlist ';'      // 不透明门
    | 'opaque' ID '(' idlist ')' idlist ';'
    | qop                         // 量子操作
    | 'if' '(' ID '==' nninteger ')' qop
    | 'barrier' anylist ';'
    ;


// include 语句定义
includeStatement
    : 'include' STRING ';'
    ;


// 寄存器声明
decl
    : 'qreg' ID '[' nninteger ']' ';'
    | 'creg' ID '[' nninteger ']' ';'
    ;


// 门定义（包含 goplist 的内容体）
gatedecl
    : 'gate' ID idlist '{' goplist '}'               // 无参数的 gate
    | 'gate' ID '(' ')' idlist '{' goplist '}'       // 空参数列表的 gate
    | 'gate' ID '(' idlist ')' idlist '{' goplist '}' // 带参数的 gate
    ;

goplist
    : (uop | 'barrier' idlist ';')*
    ;


// 量子操作
qop
    : uop
    | 'measure' argument '->' argument ';'
    | 'reset' argument ';'
    ;

// 基本量子操作
uop
    : 'U' '(' explist ')' argument ';'
    | 'CX' argument ',' argument ';'
    | ID anylist ';'
    | ID '(' explist ')' anylist ';'
    ;

// 通用列表
anylist
    : idlist
    | mixedlist
    ;

idlist
    : ID (',' ID)*
    ;

mixedlist
    : ID ('[' nninteger ']')? (',' ID ('[' nninteger ']')?)*
    ;

// 参数与标识符
argument
    : ID
    | ID '[' nninteger ']'
    ;

explist
    : exp (',' exp)*
    ;

// 表达式
//exp
//    : real
//    | nninteger
//    | 'pi'
//    | ID
//    | exp '+' exp
//    | exp '-' exp
//    | exp '*' exp
//    | exp '/' exp
//    | '-' exp
//    | exp '^' exp
//    | '(' exp ')'
//    | unaryop '(' exp ')'
//    ;
// 表达式，考虑优先级
exp
    : additiveExp
    ;

additiveExp
    : additiveExp '+' multiplicativeExp      // Addition
    | additiveExp '-' multiplicativeExp      // Subtraction
    | multiplicativeExp                      // Pass-through
    ;

multiplicativeExp
    : multiplicativeExp '*' exponentialExp   // Multiplication
    | multiplicativeExp '/' exponentialExp   // Division
    | exponentialExp                         // Pass-through
    ;

exponentialExp
    : unaryExp '^' exponentialExp            // Exponentiation (Right-associative)
    | unaryExp                               // Pass-through
    ;

unaryExp
    : '-' unaryExp                           // Unary negation
    | primaryExp                             // Pass-through
    ;

primaryExp
    : real                                   // Real numbers
    | nninteger                              // Non-negative integers
    | 'pi'                                   // Constant pi
    | ID                                     // Identifiers
    | '(' exp ')'                            // Parentheses
    | unaryop '(' exp ')'                    // Unary operations (e.g., sin, cos)
    ;


// 单目操作符
unaryop
    : 'sin' | 'cos' | 'tan' | 'exp' | 'ln' | 'sqrt' | 'asin' | 'acos' | 'atan'
    ;

// 字符串定义
STRING : '"' (~["\r\n])* '"';

// 数值定义
real
    : REAL
    ;

nninteger
    : NNINTEGER
    ;

// 标识符
ID  : [a-z] [A-Za-z0-9_]*;

// 实数和非负整数定义
REAL : ([0-9]+ '.' [0-9]* | '.' [0-9]+) ([eE] [-+]? [0-9]+)?;
NNINTEGER : [1-9][0-9]* | '0';

// 忽略的空白字符
WS : [ \t\r\n]+ -> skip;

// 忽略单行注释
COMMENT : '//' ~[\r\n]* -> skip;
